/*MyPhotoIndex Free Photo Organizer <www.myphotoindex.com>
  Copyright (C) <2006-2009>  <Asaf Yarkoni asaf@yarkoni.net>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using MyPhotoIndex.Utilities;
using System.Security.Permissions;
using MyPhotoIndex.Interfaces;

namespace MyPhotoIndex.Controls
{
    public partial class MyPhotoIndexThumbnailViewer
    {
        private MiniThumbnailViewer m_mtv;

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Left:
                    SelectPreviousThumbnail();
                    return true;

                case Keys.Right:
                    SelectNextThumbnail();
                    return true;

                case Keys.Up:
                    SelectPreviousRow();
                    return true;

                case Keys.Down:
                    SelectNextRow();
                    return true;

                case Keys.Apps:
                    SimulateMouseClickOnSelectedImage(MouseButtons.Right);
                    return true;

                case Keys.PageUp:
                    SelectPreviosPage();
                    return true;

                case Keys.PageDown:
                    SelectNextPage();
                    return true;

                case Keys.Home:
                    SelectFirstPage();
                    return true;

                case  Keys.End:
                    SelectLastPage();
                    return true;
            }
            
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void SelectLastPage()
        {
            this.vScrollBar1.Value = vScrollBar1.Maximum;
            ClearSelection();

            int nextSelectedImageId = ImageOffsetToImageId(m_firstImageDrawn);
            SelectImage(nextSelectedImageId, true);
        }

        private void SelectFirstPage()
        {
            this.vScrollBar1.Value = 0;
            ClearSelection();

            int nextSelectedImageId = ImageOffsetToImageId(m_firstImageDrawn);
            SelectImage(nextSelectedImageId, true);
        }

        private void SelectNextPage()
        {
            this.vScrollBar1.Value += Math.Min(this.m_numOfRows + 1, (this.vScrollBar1.Maximum - this.vScrollBar1.Value));
            ClearSelection();
            
            int nextSelectedImageId = ImageOffsetToImageId(m_firstImageDrawn);
            SelectImage(nextSelectedImageId, true);
        }

        private void SelectPreviosPage()
        {
            this.vScrollBar1.Value -= Math.Min(this.m_numOfRows + 1, this.vScrollBar1.Value);
            ClearSelection();

            int nextSelectedImageId = ImageOffsetToImageId(m_firstImageDrawn);
            SelectImage(nextSelectedImageId, true);
        }

        public void SelectPreviousRow()
        {
            bool addSelected = ((Control.ModifierKeys & Keys.Control) == Keys.Control);

            if (m_selectedImages.Count == 0)
            {
                SelectFirstImage();
                return;
            }

            int selectedImageId = m_selectedImages[m_selectedImages.Count - 1];
            int selectedImageOffset = ImageIdToImageOffset(selectedImageId);
            if (m_imageList == null)
            {
                return;
            }

            int nextIndex = selectedImageOffset - m_numOfCols;
            if (nextIndex >= 0)
            {
                if (addSelected == false)
                {
                    ClearSelection();
                }

                int nextSelectedImageId = ImageOffsetToImageId(nextIndex);
                SelectImage(nextSelectedImageId, true);

                ScrollToSelected();
            }
        }

        public void SelectNextRow()
        {
            bool addSelected = ((Control.ModifierKeys & Keys.Control) == Keys.Control);

            if (m_selectedImages.Count == 0)
            {
                SelectFirstImage();
                return;
            }

            int selectedImageId = m_selectedImages[m_selectedImages.Count - 1];
            int selectedImageOffset = ImageIdToImageOffset(selectedImageId);
            if (m_imageList == null)
            {
                return;
            }

            int nextIndex = selectedImageOffset + m_numOfCols;
            if (nextIndex < m_imageList.Count)
            {
                if (addSelected == false)
                {
                    ClearSelection();
                }

                int nextSelectedImageId = ImageOffsetToImageId(nextIndex);
                SelectImage(nextSelectedImageId, true);

                ScrollToSelected();
            }
        }

        public int SelectNextThumbnail()
        {
            return GetNextThumbnail(true);
        }

        public int GetNextThumbnail(bool select)
        {
            bool addSelected = ((Control.ModifierKeys & Keys.Control) == Keys.Control);

            if (m_selectedImages.Count == 0)
            {
                SelectFirstImage();
                return ImageOffsetToImageId(0);
            }

            int selectedImageId = m_selectedImages[m_selectedImages.Count - 1];
            int selectedImageOffset = ImageIdToImageOffset(selectedImageId);
            if (m_imageList == null ||
                m_imageList.Count == selectedImageOffset ||
                m_imageList.Count <= (selectedImageOffset + 1))
            {
                return selectedImageId;
            }

            int nextSelectedImageId = ImageOffsetToImageId(selectedImageOffset + 1);

            if (select == true)
            {
                if (addSelected == false)
                {
                    ClearSelection();
                }

                SelectImage(nextSelectedImageId, true);
                ScrollToSelected();
            }

            return nextSelectedImageId;
        }

        public void SelectPreviousThumbnail()
        {
            bool addSelected = ((Control.ModifierKeys & Keys.Control) == Keys.Control);

            if (m_selectedImages.Count == 0)
            {
                SelectFirstImage();
                return;
            }

            int selectedImageId = m_selectedImages[0];
            int selectedImageOffset = ImageIdToImageOffset(selectedImageId);
            if (m_imageList == null ||
                0 >= selectedImageOffset)
            {
                return;
            }

            if (addSelected == false)
            {
                ClearSelection();
            }

            int previousSelectedImageId = ImageOffsetToImageId(selectedImageOffset - 1);
            SelectImage(previousSelectedImageId, true);
            ScrollToSelected();
        }

        public void SimulateMouseClickOnSelectedImage(MouseButtons mouseButtons)
        {
            if (m_selectedImages.Count == 0)
            {
                return;
            }

            try
            {
                int selectedImageId = m_selectedImages[m_selectedImages.Count - 1];
                ScrollToSelected();

                Thumbnail thumb = GetDrawnImage(selectedImageId);
                if (thumb != null)
                {
                    if (ThumbnailMouseClickEvent != null)
                    {
                        ThumbnailMouseClickEvent.Invoke(thumb, 
                            new ThumbnailMouseEventArgs(thumb.ImageId, 
                            mouseButtons, Control.ModifierKeys, 
                            thumb.ImageDrawingRect.X, thumb.ImageDrawingRect.Y, 
                            ThumbnailIcon.Invalid, thumb.ImageDrawingRect));
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }
        }

        public void ShowPhotoBar()
        {
            return;
            //if (m_mtv == null)
            //{
            //    m_mtv = new MiniThumbnailViewer(this);
            //    m_mtv.Parent = this;
    
            //    m_mtv.ImageList = this.ImageList;
            //}

            //this.VerticalAlignment = System.Windows.Forms.VisualStyles.VerticalAlignment.Bottom;
            //UpdateMiniThumbSize();

            //m_mtv.Show();
        }

        private void UpdateMiniThumbSize()
        {
            if (m_mtv != null)
            {
                m_mtv.Width = (int)m_maxPictureSize/* - m_imageLeftMargin - m_imageRightMargin*/;
                m_mtv.Height = m_pageTopBorder - 5/* - m_imageBottomMargin*/;
                int x = ((this.ClientRectangle.Width - m_mtv.Width) / 2) - (this.vScrollBar1.Width / 2);
                int y = (m_pageTopBorder - m_mtv.Height) / 2;

                m_mtv.Location = new System.Drawing.Point(x, 0);
            }
        }

        public void HidePhotoBar()
        {
            return;
            //if (m_mtv != null)
            //{
            //    m_mtv.Hide();
            //}

            //this.VerticalAlignment = System.Windows.Forms.VisualStyles.VerticalAlignment.Center;
        }

        public void ToggleChecked(int imageId)
        {
            if (IsChecked(imageId) == false)
            {
                m_checkedImages.Add(imageId);
                m_uncheckedImages.Remove(imageId);
            }
            else
            {
                m_checkedImages.Remove(imageId);
                m_uncheckedImages.Add(imageId);
            }

            Thumbnail thumbnail = GetDrawnImage(imageId);
            if (thumbnail != null)
            {
                this.Invalidate(thumbnail.FrameDrawingRect);
            }

            if (CheckChangedEvent != null)
            {
                CheckChangedEvent.Invoke(thumbnail, EventArgs.Empty);
            }
        }
    }
}
